#!/bin/bash
set -o pipefail

DATE=`date +%Y%m%d_%H%M%S`

#每个数据库保留文件个数
REMAIN_COUNT=30
#备份超时时间
TIMEOUT=5m
#根目录
BASE_DIR=$(cd `dirname $0`;pwd)
#数据库配置文件位置
DB_CONFIG_INI=$BASE_DIR/dbconfig.ini
#邮件配置位置
MAIL_CONFIG_INI=$BASE_DIR/mailconfig.ini
#备份文件夹
BACK_DIR=$BASE_DIR/mysqldump
#日志存放位置
LOG_DIR=$BASE_DIR/logs

#数据库配置中的KEY
DB_HOST_KEY="host"
DB_PORT_KEY="port"
DB_USER_KEY="username"
DB_PWD_KEY="password"

#邮件配置中的KEY
MAIL_USER_KEY="mail"
MAIL_WORD_KEY="word"
MAIL_SIZE_KEY="size"


#关键字
SUCCESS="success"
FAIL="fail"


#备份文件夹位置
backPath(){
    for dbstr in "$@";do
      echo $BACK_DIR/$(echo $dbstr | awk -F "@" -vs=/ '{print $1s$2}')
    done
}

#备份文件位置
backFile(){
    for dbstr in "$@";do
          echo $(backPath $dbstr)/$DATE@$(echo $dbstr | awk -F "@" '{print $NF}').sql.gz
    done
}

#读取配置
config(){
    iniFile=$1
    section=$2
    option=$3
    if [ "${section}" = "" ];then
        allSections=$(awk -F '[][]' '/\[.*]/{print $2}' ${iniFile})
        iniSections=(${allSections// /})
        echo ${iniSections[@]}
    elif [ "${section}" != "" ] && [ "${option}" != "" ];then
        iniValue=`awk -F '=' "/\[${section}\]/{a=1}a==1" ${iniFile}|sed -e '1d' -e '/^$/d' -e '/^\[.*\]/,$d' -e "/^${option}.*=.*/!d" -e "s/^${option}.*= *//"`
        echo ${iniValue}
    fi
}


#日志文件
mkdir -p $LOG_DIR
LOG=$LOG_DIR/$DATE.log

#数据库备份
list=$(config $DB_CONFIG_INI)
for dbstr in ${list[@]}
do
    echo "=====开始备份 $dbstr====="

    #数据库信息
    DB_NAME=$(echo $dbstr | awk -F "@" '{print $NF}')
    DB_HOST=$(config $DB_CONFIG_INI $dbstr $DB_HOST_KEY)
    DB_PORT=$(config $DB_CONFIG_INI $dbstr $DB_PORT_KEY)
    DB_USER=$(config $DB_CONFIG_INI $dbstr $DB_USER_KEY)
    DB_PWD=$(config $DB_CONFIG_INI $dbstr $DB_PWD_KEY)

    #备份文件位置
    BACK_PATH=$(backPath $dbstr)
    mkdir -p $BACK_PATH
    BACK_FILE=$(backFile $dbstr)

    #开始导出
    timeout --foreground -s 9 $TIMEOUT mysqldump --column-statistics=0 --routines --single-transaction --quick --skip-add-locks -h$DB_HOST -P$DB_PORT -u$DB_USER -p$DB_PWD $DB_NAME | gzip > $BACK_FILE

    #写日志
    if [ $? -eq 0 ]; then
        echo "$dbstr $SUCCESS"
        echo "$dbstr $SUCCESS">>$LOG
    else
        rm $BACK_FILE
        echo "$dbstr $FAIL"
        echo "$dbstr $FAIL">>$LOG
    fi

    #删除之前的备份
    cd $BACK_PATH
    CURR_COUNT=$(ls|grep $DB_NAME|wc -l)
    if [ $CURR_COUNT -gt $REMAIN_COUNT ]; then
        rm `ls -t|grep $DB_NAME|tail -n +$(($REMAIN_COUNT+1))`
    fi

done

#给项目负责人发邮件
if [ -f $MAIL_CONFIG_INI ]; then

    list=$(config $MAIL_CONFIG_INI)
    for mailstr in ${list[@]}
    do
        echo "=====给 $mailstr 发邮件====="

        #邮件信息
        MAIL_USER=$(config $MAIL_CONFIG_INI $mailstr $MAIL_USER_KEY)
        MAIL_WORD=$(config $MAIL_CONFIG_INI $mailstr $MAIL_WORD_KEY)
        MAIL_SIZE=$(config $MAIL_CONFIG_INI $mailstr $MAIL_SIZE_KEY)
        #发邮件
        FAIL_COUNT=$(grep $FAIL $LOG|grep -E "$MAIL_WORD"|wc -l)
		    #附件信息
        if [[ $MAIL_SIZE ]];then
             fileParam=$(find $BACK_DIR -name "*$DATE*" -size -$MAIL_SIZE|grep -E "$MAIL_WORD"|awk '{printf " -a %s",$1}')
        else
             fileParam=""
        fi
        if [[ $MAIL_WORD ]];then
          grep -E "$MAIL_WORD" $LOG|mail -s 数据备份_失败$FAIL_COUNT条 $fileParam $MAIL_USER
        else
          cat $LOG|mail -s 数据备份_失败$FAIL_COUNT条 $fileParam $MAIL_USER
        fi
    done
fi
